/*******************************************************************************
 ** Qt Advanced Docking System
 ** Copyright (C) 2017 Uwe Kindler
 **
 ** This library is free software; you can redistribute it and/or
 ** modify it under the terms of the GNU Lesser General Public
 ** License as published by the Free Software Foundation; either
 ** version 2.1 of the License, or (at your option) any later version.
 **
 ** This library is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ** Lesser General Public License for more details.
 **
 ** You should have received a copy of the GNU Lesser General Public
 ** License along with this library; If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

//============================================================================
/// \file   FloatingWidgetTitleBar.cpp
/// \author Uwe Kindler
/// \date   13.05.2019
/// \brief  Implementation of CFloatingWidgetTitleBar class
//============================================================================

//============================================================================
//                                   INCLUDES
//============================================================================
#include "FloatingWidgetTitleBar.h"

#include <iostream>

#include <QHBoxLayout>
#include <QPushButton>
#include <QToolButton>
#include <QPixmap>
#include <QStyle>
#include <QMouseEvent>

#include "ads_globals.h"
#include "ElidingLabel.h"
#include "FloatingDockContainer.h"

namespace ads
{

using tTabLabel = CElidingLabel;
using tCloseButton = QToolButton;
using tMaximizeButton  = QToolButton;

/**
 * @brief CFloatingWidgetTitleBar 的私有数据类
 */
struct FloatingWidgetTitleBarPrivate
{
    CFloatingWidgetTitleBar *_this; ///< 公共接口类
    QLabel *IconLabel = nullptr;
    tTabLabel *TitleLabel;
    tCloseButton *CloseButton = nullptr;
    tMaximizeButton* MaximizeButton = nullptr;
    CFloatingDockContainer *FloatingWidget = nullptr;
    eDragState DragState = DraggingInactive;
    QIcon MaximizeIcon;
    QIcon NormalIcon;
    bool Maximized = false;

    /**
     * 构造函数
     * @param _public 公共接口类指针
     */
    FloatingWidgetTitleBarPrivate(CFloatingWidgetTitleBar *_public) :
        _this(_public)
    {
    }

    /**
     * 创建包含所有控件的完整布局
     */
    void createLayout();
};
//============================================================================
// FloatingWidgetTitleBarPrivate类
//============================================================================

// 创建布局
void FloatingWidgetTitleBarPrivate::createLayout()
{
    // 创建标题标签
    TitleLabel = new tTabLabel();
    TitleLabel->setElideMode(Qt::ElideRight);
    TitleLabel->setText("DockWidget->windowTitle()");
    TitleLabel->setObjectName("floatingTitleLabel");
    TitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    // 创建关闭按钮
    CloseButton = new tCloseButton();
    CloseButton->setObjectName("floatingTitleCloseButton");
    CloseButton->setAutoRaise(true);
    QIcon CloseIcon;
    QPixmap normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
    CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
    CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
    CloseButton->setIcon(_this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
    CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    CloseButton->setVisible(true);
    CloseButton->setFocusPolicy(Qt::NoFocus);
    _this->connect(CloseButton, SIGNAL(clicked()), SIGNAL(closeRequested()));

    // 创建最大化按钮
    MaximizeButton = new tMaximizeButton();
    MaximizeButton->setObjectName("floatingTitleMaximizeButton");
    MaximizeButton->setAutoRaise(true);
    MaximizeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    MaximizeButton->setVisible(true);
    MaximizeButton->setFocusPolicy(Qt::NoFocus);
    _this->connect(MaximizeButton, &QPushButton::clicked, _this, &CFloatingWidgetTitleBar::maximizeRequested);

    // 设置布局
    QFontMetrics fm(TitleLabel->font());
    int Spacing = qRound(fm.height() / 4.0);
    QBoxLayout *Layout = new QBoxLayout(QBoxLayout::LeftToRight);
    Layout->setContentsMargins(6, 0, 0, 0);
    Layout->setSpacing(0);
    _this->setLayout(Layout);
    Layout->addWidget(TitleLabel, 1);
    Layout->addSpacing(Spacing);
    Layout->addWidget(MaximizeButton);
    Layout->addWidget(CloseButton);
    Layout->setAlignment(Qt::AlignCenter);
    TitleLabel->setVisible(true);
}

//============================================================================
// CFloatingWidgetTitleBar类
//============================================================================

// 构造函数
CFloatingWidgetTitleBar::CFloatingWidgetTitleBar(CFloatingDockContainer *parent) :
    QFrame(parent),
    d(new FloatingWidgetTitleBarPrivate(this))
{
    d->FloatingWidget = parent;
    d->createLayout();
    auto normalPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, d->MaximizeButton);
    d->NormalIcon.addPixmap(normalPixmap, QIcon::Normal);
    d->NormalIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
    auto maxPixmap = this->style()->standardPixmap(QStyle::SP_TitleBarMaxButton, 0, d->MaximizeButton);
    d->MaximizeIcon.addPixmap(maxPixmap, QIcon::Normal);
    d->MaximizeIcon.addPixmap(internal::createTransparentPixmap(maxPixmap, 0.25), QIcon::Disabled);
    setMaximizedIcon(d->Maximized);
}

// 析构函数
CFloatingWidgetTitleBar::~CFloatingWidgetTitleBar()
{
    delete d;
}

// 鼠标按下事件
void CFloatingWidgetTitleBar::mousePressEvent(QMouseEvent *ev)
{
    if (ev->button() == Qt::LeftButton)
    {
        d->DragState = DraggingFloatingWidget;
        d->FloatingWidget->startDragging(ev->pos(), d->FloatingWidget->size(),
            this);
        return;
    }
    Super::mousePressEvent(ev);
}

// 鼠标释放事件
void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *ev)
{
    d->DragState = DraggingInactive;
    if (d->FloatingWidget)
    {
        d->FloatingWidget->finishDragging();
    }
    Super::mouseReleaseEvent(ev);
}


//============================================================================
// CFloatingWidgetTitleBar::mouseMoveEvent
// 描述：处理浮动窗口标题栏的鼠标移动事件。
//============================================================================
void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
{
    // 如果左键未按下或拖动状态为DraggingInactive，则调用基类的mouseMoveEvent并返回。
    if (!(ev->buttons() & Qt::LeftButton) || d->DragState == DraggingInactive)
    {
        Super::mouseMoveEvent(ev);
        return;
    }

    // 如果拖动状态为DraggingFloatingWidget，则移动浮动窗口。
    if (d->DragState == DraggingFloatingWidget)
    {
        if (d->FloatingWidget->isMaximized())
        {
            d->FloatingWidget->showNormal(true);
        }
        d->FloatingWidget->moveFloating();
        Super::mouseMoveEvent(ev);
        return;
    }

    // 调用基类的mouseMoveEvent。
    Super::mouseMoveEvent(ev);
}

//============================================================================
// CFloatingWidgetTitleBar::enableCloseButton
// 描述：启用或禁用标题栏的关闭按钮。
//============================================================================
void CFloatingWidgetTitleBar::enableCloseButton(bool Enable)
{
    d->CloseButton->setEnabled(Enable);
}

//============================================================================
// CFloatingWidgetTitleBar::setTitle
// 描述：设置标题栏的标题。
//============================================================================
void CFloatingWidgetTitleBar::setTitle(const QString &Text)
{
    d->TitleLabel->setText(Text);
}

//============================================================================
// CFloatingWidgetTitleBar::updateStyle
// 描述：更新标题栏的样式。
//============================================================================
void CFloatingWidgetTitleBar::updateStyle()
{
    internal::repolishStyle(this, internal::RepolishDirectChildren);
}

//============================================================================
// CFloatingWidgetTitleBar::mouseDoubleClickEvent
// 描述：处理标题栏的鼠标双击事件。
//============================================================================
void CFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    // 如果按下了左键，发出maximizeRequested信号并接受事件。
    if (event->buttons() & Qt::LeftButton)
    {
        emit maximizeRequested();
        event->accept();
    }
    else
    {
        // 调用基类的mouseDoubleClickEvent。
        QWidget::mouseDoubleClickEvent(event);
    }
}

//============================================================================
// CFloatingWidgetTitleBar::setMaximizedIcon
// 描述：设置窗口最大化时最大化按钮的图标。
//============================================================================
void CFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)
{
    d->Maximized = maximized;
    if (maximized)
    {
        d->MaximizeButton->setIcon(d->NormalIcon);
    }
    else
    {
        d->MaximizeButton->setIcon(d->MaximizeIcon);
    }
}

//============================================================================
// CFloatingWidgetTitleBar::setMaximizeIcon
// 描述：设置最大化按钮的图标。
//============================================================================
void CFloatingWidgetTitleBar::setMaximizeIcon(const QIcon& Icon)
{
    d->MaximizeIcon = Icon;
    if (d->Maximized)
    {
        setMaximizedIcon(d->Maximized);
    }
}

//============================================================================
// CFloatingWidgetTitleBar::setNormalIcon
// 描述：设置窗口非最大化时最大化按钮的图标。
//============================================================================
void CFloatingWidgetTitleBar::setNormalIcon(const QIcon& Icon)
{
    d->NormalIcon = Icon;
    if (!d->Maximized)
    {
        setMaximizedIcon(d->Maximized);
    }
}

//============================================================================
// CFloatingWidgetTitleBar::maximizeIcon
// 描述：返回最大化按钮的图标。
//============================================================================
QIcon CFloatingWidgetTitleBar::maximizeIcon() const
{
    return d->MaximizeIcon;
}

//============================================================================
// CFloatingWidgetTitleBar::normalIcon
// 描述：返回窗口非最大化时最大化按钮的图标。
//============================================================================
QIcon CFloatingWidgetTitleBar::normalIcon() const
{
    return d->NormalIcon;
}


} // namespace ads
